﻿<!doctype html>
<html>
<head>
    <title>SpreadJS - Inc5000 Slicer</title>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    
    <link href="../../../external/spreadjs/css/gcspread.sheets.excel2013white.9.40.20161.0.css" rel="stylesheet" type="text/css" />

    <script src="../../../external/external/jquery-1.8.2.min.js" type="text/javascript"></script>

    <script type="text/javascript" src="../../../external/spreadjs/gcspread.sheets.all.9.40.20161.0.min.js"></script>

    <style type="text/css">
        /*css_begin*/
        button {
            background: #9fd5b7;
            border: none;
            border-radius: 0;
            margin-left: 3px;
        }
        button:hover {
            background: #ababab;
            border: none;
            border-radius: 0;
        }
        /*css_end*/
    </style>

    <script id="scriptInit" type="text/javascript">
        /*code_begin*/
        $(document).ready(function () {
            var spread = new GcSpread.Sheets.Spread(document.getElementById("ss"));
            spread.setTabStripRatio(0.6);
            initSpread(spread);
        });
        
        function initSpread(spread) {
            $.ajax({
                url: "Inc5000_2014_json.txt",
                datatype: "text",
                beforeSend: function (xhr) {
                },
                success: function (data) {
                    if (data.length > 0) {
                        var jsonData = JSON.parse(data);
                        if (jsonData) {
                            if (!spread) {
                                return;
                            }
                            var sheet = spread.getActiveSheet();
                            initSlicer(sheet, jsonData);
                        }
                    }
                },
                error: function (ex) {
                    alert(ex);
                }
            });
        }

        function parseJSONToArray(datas) {
            if (!datas || datas.length <= 0) {
                return;
            }
            var columnNames = Object.keys(datas[0]), keyCount = columnNames.length,
                arrayDatas = [];
            for (var i = 0, len = datas.length; i < len; i++) {
                var data = datas[i];
                if (data) {
                    var dataItem = [];
                    arrayDatas.push(dataItem);
                    for (var j = 0; j < keyCount; j++) {
                        dataItem.push(data[columnNames[j]]);
                    }
                }
            }
            return {
                columnNames: columnNames,
                arrayDatas: arrayDatas
            };
        }

        function getMaxInArray(array) {
            if (!array || array.length <= 0) {
                return;
            }
            var max = array[0];
            for (var i = 1, len = array.length; i < len; i++) {
                if (array[i] > max) {
                    max = array[i];
                }
            }
            return max;
        }

        function initSlicer(sheet, datas) {
            //bind data to sheet.
            sheet.isPaintSuspended(true);
            sheet.setName("The 2014 Inc. 5000.");
            sheet.setDataSource(datas);
            sheet.setColumnCount(20);
            sheet.isPaintSuspended(false);
            //overide the onFiltered
            GcSpread.Slicer.GeneralSlicerData.prototype.onFiltered = function (filteredIndexes, isPreview) {
                for (var i = 0; i < this._listeners.length; i++) {
                    this._listeners[i]({ dataIndexes: filteredIndexes, isPreview: isPreview });
                }
            };

            //initalize the slicerData
            var ret = parseJSONToArray(datas);
            var slicerData = new GcSpread.Slicer.GeneralSlicerData(ret.arrayDatas, ret.columnNames);

            //add action after the data of the slicer has been filtered
            var currentColumnName = "";
            function refreshList(slicerData) {
                // update charts
                if (currentColumnName !== "years on list") {
                    yearsOnListChart.setSeries([{ data: getSeriesByXAxisScope(yearsOnListChart.getOption().xAxis[0].data, "years on list", slicerData) }]);
                }
                if (currentColumnName !== "workers") {
                    workersChart.setSeries([{ data: getSeriesByXAxisScope(workersChart.getOption().xAxis[0].data, "workers", slicerData) }]);
                }
                // update the sheet
                var filteredRowIndexs = slicerData.getFilteredRowIndexes();
                sheet.isPaintSuspended(true);
                sheet.suspendEvent();
                for (var r = 0, len = sheet.getRowCount() ; r < len; r++) {
                    sheet.setRowVisible(r, false);
                }
                for (var i = 0, len = filteredRowIndexs.length; i < len; i++) {
                    sheet.setRowVisible(filteredRowIndexs[i], true);
                }
                sheet.resumeEvent();
                sheet.isPaintSuspended(false);
            }
            slicerData.attachListener(function () {
                refreshList(slicerData);
            });

            function getSeriesByXAxisScope(xAxis, columnName, slicerData) {
                if (!xAxis || xAxis.length <= 0 || !slicerData) {
                    return;
                }
                var series = [], data = slicerData.getData(columnName),
                    filterdRowIndexes = slicerData.getFilteredRowIndexes();
                for (var x = 0, len1 = xAxis.length; x < len1; x++) {
                    var scopeStart = 0;
                    if (x > 0) {
                        scopeStart = xAxis[x - 1];
                    }
                    var scopeEnd = xAxis[x];
                    var seriesItem = 0;
                    for (var i = 0, len = filterdRowIndexes.length; i < len; i++) {
                        var rowIndex = filterdRowIndexes[i], dataItem = data[rowIndex];
                        if (dataItem >= scopeStart && dataItem < scopeEnd) {
                            seriesItem++;
                        }
                    }
                    series.push(seriesItem);
                }
                return series;
            }

            function getSeriesByXAxis(xAxis, columnName, slicerData) {
                if (!xAxis || xAxis.length <= 0 || !slicerData) {
                    return;
                }
                var series = [], datas = slicerData.getData(columnName),
                    filterdRowIndexes = slicerData.getFilteredRowIndexes();
                for (var i = 0, len = xAxis.length; i < len; i++) {
                    var item = xAxis[i];
                    var seriesItem = 0;
                    for (var j = 0, len1 = filterdRowIndexes.length; j < len1; j++) {
                        var rowIndex = filterdRowIndexes[j];
                        if (item === datas[rowIndex]) {
                            seriesItem++;
                        }
                    }
                    series.push(seriesItem);
                }
                return series;
            }

            function verticalBarChartSlicer(container, columnName, slicerData, title, legend) {
                //init DOMs
                var $chartDiv = $("<div style='width:100%;height:90%'></div>"),
                    $footerDiv = $("<div style='width:100%;height:9%'></div>"),
                    $textSpan = $("<span></span>"), $removeFilter = $("<button>Remove Filter</button>");
                $removeFilter.click(function () {
                    currentColumnName = "";
                    slicerData.doUnfilter(columnName);
                    $footerDiv.hide();
                });
                $footerDiv.append($textSpan);
                $footerDiv.append($removeFilter);
                $footerDiv.hide();
                $(container).append($chartDiv);
                $(container).append($footerDiv);

                //prepare xAxis data for chart
                var exclusiveData = slicerData.getExclusiveData(columnName);
                var maxValue = getMaxInArray(exclusiveData), series = [], xAxis = [];
                if (columnName === "years on list") {
                    var xAxisCount = 6, xTick = Math.floor(maxValue / xAxisCount);
                    for (var i = 1; i <= xAxisCount; i++) {
                        xAxis.push(xTick * i);
                    }
                } else if (columnName === "workers") {
                    if (typeof maxValue === "number") {
                        var base = 1;
                        while (maxValue > 1) {
                            xAxis.push(Math.pow(10, base));
                            base++;
                            maxValue = parseInt(maxValue / 10);
                        }
                    }
                }
                //prepare series data for chart
                series = getSeriesByXAxisScope(xAxis, columnName, slicerData);
                //create chart and set the chart option
                var verticalChart = echarts.init($chartDiv[0]);
                var option = {
                    title: {
                        subtext: title,
                    },
                    legend: {
                        data: [legend]
                    },
                    grid: {
                        x: "15%",
                        width: "80%",
                        x2: "5%",
                        y: "30%",
                        height: "60%",
                        y2: "15%"
                    },
                    xAxis: [
                        {
                            type: 'category',
                            data: xAxis,
                            axisTick: {
                                show: true,
                                length: 2,
                                lineStyle: {
                                    color: "#333",
                                    width: 1
                                }
                            }
                        }
                    ],
                    yAxis: [
                        {
                            type: 'value'
                        }
                    ],
                    series: [
                        {
                            name: legend,
                            type: "bar",
                            data: series,
                            itemStyle: {
                                normal: {
                                    color: "#9fd5b7",
                                    label: {
                                        show: true
                                    }
                                },
                                emphasis: {
                                    color: "#ababab"
                                }
                            }
                        }
                    ]
                };
                verticalChart.setOption(option);
                //bind the click event
                function clickHander(param) {
                    var dataIndex = param.dataIndex;
                    var endScope = xAxis[dataIndex], startScope = 0;
                    if (dataIndex > 0) {
                        startScope = xAxis[dataIndex - 1];
                    }
                    $textSpan.text(title + ": " + startScope + " to " + endScope);
                    $footerDiv.show();
                    var indexes = [];
                    for (var i = 0, len = exclusiveData.length; i < len; i++) {
                        if (exclusiveData[i] >= startScope && exclusiveData[i] < endScope) {
                            indexes.push(i);
                        }
                    }
                    currentColumnName = columnName;
                    slicerData.doFilter(columnName, { exclusiveRowIndexes: indexes });
                }
                verticalChart.on("click", clickHander);

                return verticalChart;
            }

            var yearsOnListChart = verticalBarChartSlicer($("#yearsOnList")[0], "years on list", slicerData, "Years on the List", "Number of companies");
            var workersChart = verticalBarChartSlicer($("#workers")[0], "workers", slicerData, "Workers", "Number of companies");
        }
        /*code_end*/
    </script>

</head>
<body>
    <div class="sample-turtorial">
        <div style="width: 96%;">
            <div id="workers" style="position: absolute; left: 0; top: 0; width:251px; height:250px;"></div>
            <div id="yearsOnList" style="position: absolute; left: 260px; top: 0; width: 280px; height: 250px;"></div>
            <div id="ss" style="position: absolute; left: 0; top: 260px; width: 98%; height: 370px; border: 1px solid gray;"></div>
        </div>
    </div>
</body>
</html>